/*
 * Copyright (c) 2006-2025, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2025-02-19     RT-Thread    first version
 */

#include <rtthread.h>

#define DBG_TAG "main"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>

#include "user_mb_app.h"
extern int onenet_mqtt_init(void);
extern rt_err_t onenet_mqtt_upload_digit(const char *ds_name, const double digit);

#define PORT_NUM MB_MASTER_USING_PORT_NUM
#define PORT_BAUDRATE MB_MASTER_USING_PORT_BAUDRATE

#define PORT_PARITY MB_PAR_NONE

#define MB_POLL_THREAD_PRIORITY 10
#define MB_SEND_THREAD_PRIORITY RT_THREAD_PRIORITY_MAX - 1

#define MB_POLL_CYCLE_MS 500


#define SSID    "xjauwifi"
#define PASSWD  "Andy!@#456&*("

//------------------------------------------------
enum
{
    ID_AIR_HM_SNSR = 1,
    ID_SOIL_HM_SNSR = 2,
    ID_WIND_SPD_DIR = 3,
    ID_LIGHTSTR_SNSR = 4,

};

typedef struct w_station_tag
{
    float air_temp;
    float air_humi;

    float soil_temp;
    float soil_humi;

    uint32_t lightStrength;

    float windSpd;
    float windDir;

    float pwr_vol;
    float bat_vol;

} x_weaherStation_datapoint_t;

x_weaherStation_datapoint_t g_WS_datapoint;

//--------------------------------------------------------
extern USHORT usMRegHoldBuf[MB_MASTER_TOTAL_SLAVE_NUM][M_REG_HOLDING_NREGS];

static void send_thread_entry(void *parameter)
{
    while (1)
    {

        //-------------空气温湿度-----------------
        eMBMasterReqReadHoldingRegister(ID_AIR_HM_SNSR,      /* salve address */
                                        0,                   /* register start address */
                                        2,                   /* register total number */
                                        RT_WAITING_FOREVER); /* timeout */
        rt_thread_mdelay(1000);
        g_WS_datapoint.air_temp = usMRegHoldBuf[ID_AIR_HM_SNSR - 1][0] * 0.1;
        g_WS_datapoint.air_humi = usMRegHoldBuf[ID_AIR_HM_SNSR - 1][1] * 0.1;

        LOG_I("air_temp = %.2f, air_humi = %.2f \r\n", g_WS_datapoint.air_temp, g_WS_datapoint.air_humi);
        //-------------土壤温湿度-----------------
        eMBMasterReqReadHoldingRegister(ID_SOIL_HM_SNSR,     /* salve address */
                                        0,                   /* register start address */
                                        2,                   /* register total number */
                                        RT_WAITING_FOREVER); /* timeout */
        rt_thread_mdelay(1000);
        g_WS_datapoint.soil_temp = usMRegHoldBuf[ID_SOIL_HM_SNSR - 1][0] * 0.1;
        g_WS_datapoint.soil_humi = usMRegHoldBuf[ID_SOIL_HM_SNSR - 1][1] * 0.1;
        LOG_I("soil_temp = %.2f, soil_humi = %.2f \r\n", g_WS_datapoint.soil_temp, g_WS_datapoint.soil_humi);
        //-------------风速风向湿度-----------------
        eMBMasterReqReadHoldingRegister(ID_WIND_SPD_DIR,     /* salve address */
                                        0,                   /* register start address */
                                        2,                   /* register total number */
                                        RT_WAITING_FOREVER); /* timeout */
        rt_thread_mdelay(1000);
        g_WS_datapoint.windSpd = usMRegHoldBuf[ID_WIND_SPD_DIR - 1][0] * 0.1;
        g_WS_datapoint.windDir = usMRegHoldBuf[ID_WIND_SPD_DIR - 1][1] * 0.1;
        LOG_I("wind_spd = %.2f, wind_dir = %.2f \r\n", g_WS_datapoint.windSpd, g_WS_datapoint.windDir);
        //-------------光照传感器-----------------
        eMBMasterReqReadHoldingRegister(ID_LIGHTSTR_SNSR,    /* salve address */
                                        0,                   /* register start address */
                                        2,                   /* register total number */
                                        RT_WAITING_FOREVER); /* timeout */
        rt_thread_mdelay(1000);
        g_WS_datapoint.lightStrength = (usMRegHoldBuf[ID_LIGHTSTR_SNSR - 1][0] << 16) + usMRegHoldBuf[ID_LIGHTSTR_SNSR - 1][1];
        LOG_I("light strength = %d \r\n", g_WS_datapoint.lightStrength);
    }
}

static void mb_master_poll(void *parameter)
{
    eMBMasterInit(MB_RTU, PORT_NUM, PORT_BAUDRATE, PORT_PARITY);
    eMBMasterEnable();

    while (1)
    {
        eMBMasterPoll();
        rt_thread_mdelay(MB_POLL_CYCLE_MS);
    }
}

static int modbus_master_poll_start(void)
{
    static rt_uint8_t is_init = 0;
    rt_thread_t tid1 = RT_NULL, tid2 = RT_NULL;

    if (is_init > 0)
    {
        rt_kprintf("sample is running\n");
        return -RT_ERROR;
    }
    tid1 = rt_thread_create("md_m_poll", mb_master_poll, RT_NULL, 512 * 4, MB_POLL_THREAD_PRIORITY, 10);
    if (tid1 != RT_NULL)
    {
        rt_thread_startup(tid1);
    }
    else
    {
        goto __exit;
    }

    tid2 = rt_thread_create("md_m_send", send_thread_entry, RT_NULL, 512 * 4, MB_SEND_THREAD_PRIORITY - 2, 10);
    if (tid2 != RT_NULL)
    {
        rt_thread_startup(tid2);
    }
    else
    {
        goto __exit;
    }

    is_init = 1;
    return RT_EOK;

__exit:
    if (tid1)
        rt_thread_delete(tid1);
    if (tid2)
        rt_thread_delete(tid2);

    return -RT_ERROR;
}

MSH_CMD_EXPORT(modbus_master_poll_start, START MODBUS THREAD);

//-----------------------------------------------------------------------

/* upload value to OneNET*/
static void onenet_upload_entry(void *parameter)
{

    rt_err_t upload_res = RT_ERROR;
    while (1)
    {

        upload_res = onenet_mqtt_upload_digit("air_humi", g_WS_datapoint.air_humi);
        rt_thread_delay(rt_tick_from_millisecond(5 * 1000));
        // LOG_I("uploadRES = %d, air_humi = %.2f \r\n", upload_res, g_WS_datapoint.air_humi);
        rt_kprintf("uploadRES = %d, air_humi = %d \r\n", upload_res, (int)g_WS_datapoint.air_humi);

        upload_res = onenet_mqtt_upload_digit("air_temp", g_WS_datapoint.air_temp);
        rt_thread_delay(rt_tick_from_millisecond(5 * 1000));
        // LOG_I("uploadRES = %d, air_temp = %.2f \r\n", upload_res, g_WS_datapoint.air_temp);
        rt_kprintf("uploadRES = %d, air_temp = %d \r\n", upload_res, (int)g_WS_datapoint.air_temp);

        upload_res = onenet_mqtt_upload_digit("bat_vol", g_WS_datapoint.bat_vol);
        rt_thread_delay(rt_tick_from_millisecond(5 * 1000));
        // LOG_I("uploadRES = %d, bat_vol = %.2f \r\n", upload_res, g_WS_datapoint.bat_vol);
        rt_kprintf("uploadRES = %d, bat_vol = %d \r\n", upload_res, (int)g_WS_datapoint.bat_vol);

        upload_res = onenet_mqtt_upload_digit("light_strength", g_WS_datapoint.lightStrength);
        rt_thread_delay(rt_tick_from_millisecond(5 * 1000));
        //  LOG_I("uploadRES = %d, light_strength = %d \r\n", upload_res, g_WS_datapoint.lightStrength);
        rt_kprintf("uploadRES = %d, lightStrength = %d \r\n", upload_res, (int)g_WS_datapoint.lightStrength);

        upload_res = onenet_mqtt_upload_digit("pwr_vol", g_WS_datapoint.pwr_vol);
        rt_thread_delay(rt_tick_from_millisecond(5 * 1000));
        //  LOG_I("uploadRES = %d, pwr_vol = %.2f \r\n", upload_res, g_WS_datapoint.pwr_vol);
        rt_kprintf("uploadRES = %d, pwr_vol = %d \r\n", upload_res, (int)g_WS_datapoint.pwr_vol);

        upload_res = onenet_mqtt_upload_digit("soil_humi", g_WS_datapoint.soil_humi);
        rt_thread_delay(rt_tick_from_millisecond(5 * 1000));
        // LOG_I("uploadRES = %d, soil_humi = %.2f \r\n", upload_res, g_WS_datapoint.soil_humi);
        rt_kprintf("uploadRES = %d, soil_humi = %d \r\n", upload_res, (int)g_WS_datapoint.soil_humi);

        upload_res = onenet_mqtt_upload_digit("soil_temp", g_WS_datapoint.soil_temp);
        rt_thread_delay(rt_tick_from_millisecond(5 * 1000));
        // LOG_I("uploadRES = %d, soil_temp = %.2f \r\n", upload_res, g_WS_datapoint.soil_temp);
        rt_kprintf("uploadRES = %d, soil_temp = %d \r\n", upload_res, (int)g_WS_datapoint.soil_temp);

        upload_res = onenet_mqtt_upload_digit("wind_dir", g_WS_datapoint.windDir);
        rt_thread_delay(rt_tick_from_millisecond(5 * 1000));
        // LOG_I("uploadRES = %d, windDir = %.2f \r\n", upload_res, g_WS_datapoint.windDir);
        rt_kprintf("uploadRES = %d, soil_temp = %d \r\n", upload_res, (int)g_WS_datapoint.windDir);

        upload_res = onenet_mqtt_upload_digit("wind_spd", g_WS_datapoint.windSpd);
        rt_thread_delay(rt_tick_from_millisecond(5 * 1000));
        // LOG_I("uploadRES = %d, windSpd = %.2f \r\n", upload_res, g_WS_datapoint.windSpd);
        rt_kprintf("uploadRES = %d, windSpd = %d \r\n", upload_res, (int)g_WS_datapoint.windSpd);
    }
}

int onenet_upload_start(void)
{
    rt_thread_t tid;

    tid = rt_thread_create("one_send",
                           onenet_upload_entry,
                           RT_NULL,
                           3 * 1024,
                           RT_THREAD_PRIORITY_MAX / 3 - 1,
                           5);
    if (tid)
    {
        rt_thread_startup(tid);
    }

    return 0;
}

MSH_CMD_EXPORT(onenet_upload_start, START ONENET UPLOAD THREAD)

int main(void)
{
    //---------data sample-----------
    rt_thread_mdelay(5000);
    modbus_master_poll_start();
    //--------connect AP--------
    extern rt_err_t rt_wlan_connect(const char *ssid, const char *password);
    rt_err_t wifi_join_res = RT_ERROR;
    while(RT_EOK != wifi_join_res){
        rt_thread_mdelay(5000);
        wifi_join_res = rt_wlan_connect(SSID,PASSWD);
        LOG_E("WIFI connect failed, please check AP name and password, try to connect again......");
    }

    //--------mqtt upload-----
    extern int onenet_mqtt_init(void);
    onenet_mqtt_init();
    rt_thread_mdelay(5000);
    onenet_upload_start();


    return RT_EOK;
}
